package com.zc.trendsDispatch.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.zc.api.controller.APIController;
import com.zc.common.constant.RedisKeyConstants;
import com.zc.common.core.redis.stream.RedisStream;
import com.zc.component.gateway.annotation.Subscribe;
import com.zc.core.message.property.ReportPropertyMessage;
import com.zc.custom.domain.ChargeCustomOrderInfo;
import com.zc.custom.domain.ChargeCustomOrderInfoDetails;
import com.zc.custom.domain.ChargeCustomOrderInfoProcess;
import com.zc.custom.domain.ChargeOtherOrderInfo;
import com.zc.custom.mapper.ChargeCustomOrderInfoMapper;
import com.zc.custom.mapper.ChargeCustomOrderInfoProcessMapper;
import com.zc.custom.mapper.ChargeOtherOrderInfoMapper;
import com.zc.custom.service.IChargeCustomOrderInfoService;
import com.zc.iotDevice.domain.ChargeStationPort;
import com.zc.iotDevice.domain.ChargeStatisticsInfo;
import com.zc.iotDevice.mapper.ChargeStationPileMapper;
import com.zc.iotDevice.mapper.ChargeStationPortMapper;
import com.zc.iotDevice.mapper.ChargeStatisticsInfoMapper;
import com.zc.remoteControl.service.RemoteInstructSendService;
import com.zc.trendsDispatch.domain.ChargePileOrderInfo;
import com.zc.trendsDispatch.domain.ChargeStationStrategyAssociation;
import com.zc.trendsDispatch.domain.ChargeStationStrategyHistory;
import com.zc.trendsDispatch.mapper.ChargePileOrderInfoMapper;
import com.zc.trendsDispatch.mapper.ChargeStationStrategyAssociationMapper;
import com.zc.trendsDispatch.mapper.ChargeStationStrategyHistoryMapper;
import com.zc.websocket.handler.WebSocketService;
import com.zc.wxPay.domain.WxPay;
import com.zc.wxPay.service.WXPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zc.trendsDispatch.mapper.ChargeStationStrategyMapper;
import com.zc.trendsDispatch.domain.ChargeStationStrategy;
import com.zc.trendsDispatch.service.IChargeStationStrategyService;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;

/**
 * 场站调度策略Service业务层处理
 *
 * @author glb
 * @date 2024-02-03
 */
@Service
public class ChargeStationStrategyServiceImpl implements IChargeStationStrategyService {

    private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);

    @Autowired
    private ChargeStationStrategyMapper chargeStationStrategyMapper;

    @Autowired
    private ChargeStationStrategyAssociationMapper chargeStationStrategyAssociationMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ChargeStationPortMapper chargeStationPortMapper;

    @Autowired
    private ChargeStationPileMapper chargeStationPileMapper;

    @Autowired
    private ChargePileOrderInfoMapper chargePileOrderInfoMapper;

    @Autowired
    private ChargeCustomOrderInfoMapper chargeCustomOrderInfoMapper;

    @Resource
    private WXPayService wXPayService;//微信支付

    @Resource
    private IChargeCustomOrderInfoService chargeCustomOrderInfoService;//用户订单Service接口

    @Autowired
    private ChargeCustomOrderInfoProcessMapper chargeCustomOrderInfoProcessMapper;//订单流程Mapper接口

    @Autowired
    private ChargeStatisticsInfoMapper chargeStatisticsInfoMapper;//设备统计信息

    @Autowired
    private RemoteInstructSendService remoteInstructSendService;

    @Autowired
    private ChargeStationStrategyHistoryMapper chargeStationStrategyHistoryMapper;

    @Autowired
    private ChargeOtherOrderInfoMapper chargeOtherOrderInfoMapper;

    @Autowired
    private APIController apiController;


    /**
     * 查询场站调度策略
     *
     * @param id 场站调度策略主键
     * @return 场站调度策略
     */
    @Override
    public ChargeStationStrategy selectChargeStationStrategyById(Long id) {
        ChargeStationStrategy chargeStationStrategy = chargeStationStrategyMapper.selectChargeStationStrategyById(id);
        if (chargeStationStrategy != null) {
            ChargeStationStrategyAssociation chargeStationStrategyAssociation = new ChargeStationStrategyAssociation();
            chargeStationStrategyAssociation.setStationId(chargeStationStrategy.getStationCode());
            List<ChargeStationStrategyAssociation> chargeStationStrategyAssociations = chargeStationStrategyAssociationMapper.selectChargeStationStrategyAssociationList(chargeStationStrategyAssociation);
            String[] deviceCodeList = new String[chargeStationStrategyAssociations.size()];
            for (int i = 0; i < chargeStationStrategyAssociations.size(); i++) {
                deviceCodeList[i] = chargeStationStrategyAssociations.get(i).getDeviceId();
            }
            chargeStationStrategy.setDeviceCodeList(deviceCodeList);
        }
        return chargeStationStrategy;
    }

    /**
     * 查询场站调度策略列表
     *
     * @param chargeStationStrategy 场站调度策略
     * @return 场站调度策略
     */
    @Override
    public List<ChargeStationStrategy> selectChargeStationStrategyList(ChargeStationStrategy chargeStationStrategy) {
        return chargeStationStrategyMapper.selectChargeStationStrategyList(chargeStationStrategy);
    }

    /**
     * 新增场站调度策略
     *
     * @param chargeStationStrategy 场站调度策略
     * @return 结果
     */
    @Override
    public int insertChargeStationStrategy(ChargeStationStrategy chargeStationStrategy) {
        List<ChargeStationStrategy> chargeStationStrategies = chargeStationStrategyMapper.selectChargeStationStrategyListByCode(chargeStationStrategy.getStationCode());
        if (chargeStationStrategies.size() > 0) {
            throw new RuntimeException("此场站已存在策略");
        }
        String[] deviceCodeList = chargeStationStrategy.getDeviceCodeList();
        for (String dev : deviceCodeList) {
            ChargeStationStrategyAssociation chargeStationStrategyAssociation = new ChargeStationStrategyAssociation();
            chargeStationStrategyAssociation.setStationId(chargeStationStrategy.getStationCode());
            chargeStationStrategyAssociation.setDeviceId(dev);
            chargeStationStrategyAssociationMapper.insertChargeStationStrategyAssociation(chargeStationStrategyAssociation);
        }
        chargeStationStrategy.setCreateTime(DateUtils.getNowDate());
        return chargeStationStrategyMapper.insertChargeStationStrategy(chargeStationStrategy);
    }

    /**
     * 修改场站调度策略
     *
     * @param chargeStationStrategy 场站调度策略
     * @return 结果
     */
    @Override
    public int updateChargeStationStrategy(ChargeStationStrategy chargeStationStrategy) {
        chargeStationStrategyAssociationMapper.deleteChargeStationStrategyAssociationByStationCode(chargeStationStrategy.getStationCode());
        String[] deviceCodeList = chargeStationStrategy.getDeviceCodeList();
        for (String dev : deviceCodeList) {
            ChargeStationStrategyAssociation chargeStationStrategyAssociation = new ChargeStationStrategyAssociation();
            chargeStationStrategyAssociation.setStationId(chargeStationStrategy.getStationCode());
            chargeStationStrategyAssociation.setDeviceId(dev);
            chargeStationStrategyAssociationMapper.insertChargeStationStrategyAssociation(chargeStationStrategyAssociation);
        }
        chargeStationStrategy.setUpdateTime(DateUtils.getNowDate());
        return chargeStationStrategyMapper.updateChargeStationStrategy(chargeStationStrategy);
    }

    /**
     * 批量删除场站调度策略
     *
     * @param ids 需要删除的场站调度策略主键
     * @return 结果
     */
    @Override
    public int deleteChargeStationStrategyByIds(Long[] ids) {
        for (Long id : ids) {
            ChargeStationStrategy chargeStationStrategy = chargeStationStrategyMapper.selectChargeStationStrategyById(id);
            chargeStationStrategyAssociationMapper.deleteChargeStationStrategyAssociationByStationCode(chargeStationStrategy.getStationCode());
        }
        return chargeStationStrategyMapper.deleteChargeStationStrategyByIds(ids);
    }

    /**
     * 删除场站调度策略信息
     *
     * @param id 场站调度策略主键
     * @return 结果
     */
    @Override
    public int deleteChargeStationStrategyById(Long id) {
        ChargeStationStrategy chargeStationStrategy = chargeStationStrategyMapper.selectChargeStationStrategyById(id);
        chargeStationStrategyAssociationMapper.deleteChargeStationStrategyAssociationByStationCode(chargeStationStrategy.getStationCode());
        return chargeStationStrategyMapper.deleteChargeStationStrategyById(id);
    }

    /**
     * 获取场站调度策略详负载电表
     *
     * @param chargeStationStrategy 场站调度策略
     * @return 负载电表集合
     */
    @Override
    public String[] getLoad(ChargeStationStrategy chargeStationStrategy) {
        ChargeStationStrategyAssociation chargeStationStrategyAssociation = new ChargeStationStrategyAssociation();
        chargeStationStrategyAssociation.setStationId(chargeStationStrategy.getStationCode());
        List<ChargeStationStrategyAssociation> chargeStationStrategyAssociations = chargeStationStrategyAssociationMapper.selectChargeStationStrategyAssociationList(chargeStationStrategyAssociation);
        String[] deviceCodeList = new String[chargeStationStrategyAssociations.size()];
        for (int i = 0; i < chargeStationStrategyAssociations.size(); i++) {
            deviceCodeList[i] = chargeStationStrategyAssociations.get(i).getDeviceId();
        }
        return deviceCodeList;
    }

    /**
     * 统计电力数据
     */
    @Subscribe(topics = "/device/*/*/message/property/report", id = "com.zc.trendsDispatch.service.impl.ChargeStationStrategyServiceImpl.dataRetrieval")
    public Mono<Void> dataRetrieval(ReportPropertyMessage message) {
        Map<String, Object> properties = message.getProperties();
        if (properties == null) {
            return Mono.empty();
        }
        System.out.println("收到的数据：" + properties);
        String deviceId = message.getDeviceId();
        if (properties.containsKey("P")) {
            String p = String.valueOf(properties.get("P"));
            String stationCode = String.valueOf(properties.get("stationCode"));
            redisCache.setCacheMapValue(RedisKeyConstants.STATION_DEVICE_REAL_POWER.replaceAll(":station:device", ":" + stationCode + ""), deviceId, p);
        }
        if (properties.containsKey("outP")) {
            String outP = String.valueOf(properties.get("outP"));
            String stationCode = String.valueOf(properties.get("stationCode"));
            redisCache.setCacheMapValue(RedisKeyConstants.STATION_PILE_REAL_POWER.replaceAll(":station:pile", ":" + stationCode + ""), deviceId, outP);
        }

        if (properties.containsKey("instruct")) {
            String instruct = String.valueOf(properties.get("instruct"));
            if ("0x13".equals(instruct)) {
                ChargeStationPort chargeStationPort = new ChargeStationPort();
                String runningState = String.valueOf(properties.get("runningState"));
                String serviceStatus = "";
                if ("0".equals(runningState)) {
                    serviceStatus = "0";
                } else if ("1".equals(runningState)) {
                    serviceStatus = "3";
                } else if ("2".equals(runningState)) {
                    serviceStatus = "1";
                } else if ("3".equals(runningState)) {
                    serviceStatus = "2";
                    orderInfo(properties);
                }
                chargeStationPort.setServiceStatus(serviceStatus);
                chargeStationPort.setId(deviceId);
                chargeStationPortMapper.updateByPrimaryKeySelective(chargeStationPort);

            } else if ("0x15".equals(instruct)) {
                chargingHandShake(properties);
            } else if ("0x17".equals(instruct)) {
                parameterConfiguration(properties);
            } else if ("0x23".equals(instruct)) {
                chargingProcess(properties);
            } else if ("0x19".equals(instruct)) {
                endOrderInfo(properties);
            } else if ("0x3B".equals(instruct)) {
                transactionRecords(properties);
            } else if ("0x33".equals(instruct)) {
                startReply(properties);
            } else if ("0x35".equals(instruct)) {
                endReply(properties);
            } else if ("0x09".equals(instruct)) {
                billingRequest(properties);
            } else if ("0x9B".equals(instruct)) {
                QRCodeResponse(properties);
            } else if ("0x57".equals(instruct)) {
                QRCodeResponse(properties);
            } else if ("0x99".equals(instruct)) {
                dispatchRecord(properties);
            }
        }

        return Mono.empty();
    }

    @Transactional
    //充电过程中实时数据
    public void orderInfo(Map<String, Object> properties) {
        //交易流水号
        String transactionNum = String.valueOf(properties.get("transactionNum"));
        //输出电压
        String outV = String.valueOf(properties.get("outV"));
        //输出电流
        String outI = String.valueOf(properties.get("outI"));
        //充电功率
        String power = String.valueOf(properties.get("power"));
        //当前SOC
        String SOC = String.valueOf(properties.get("SOC"));
        //累计充电时间（min）
        String accumulateChargeTime = String.valueOf(properties.get("accumulateChargeTime"));
        //剩余充电时间（min）
        String residueTime = String.valueOf(properties.get("residueTime"));
        //充电度数（kwh）
        String chargeKwh = String.valueOf(properties.get("chargeKwh"));
        //计损充电度数（kwh）
        String lossChargeKwh = String.valueOf(properties.get("lossChargeKwh"));
        //已充金额
        String chargeMoney = String.valueOf(properties.get("chargeMoney"));


        //设备订单信息
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String nowTime = dateFormat.format(new Date());
        String chargeInfo = "";

        //添加到充电过程中实时数据交易订单信息
        ChargePileOrderInfo chargePileOrderInfo = new ChargePileOrderInfo(transactionNum, outV, outI, power, SOC,
                Long.parseLong(accumulateChargeTime), Long.parseLong(residueTime), chargeKwh, lossChargeKwh, new BigDecimal(chargeMoney));

        Map<String, Object> jsonMap = new HashMap<String, Object>() {{
            put("outV", outV);
            put("outI", outI);
            put("power", power);
            put("SOC", SOC);
            put("chargeKwh", chargeKwh);
        }};

        //是否有相同的订单信息
        List<ChargePileOrderInfo> chargePileOrderInfos = chargePileOrderInfoMapper.selectChargePileOrderInfoList(chargePileOrderInfo);
        if (chargePileOrderInfos != null && chargePileOrderInfos.size() > 0) {

            String chargeInfoBefore = chargePileOrderInfos.get(0).getChargeInfo();
            JSONObject jsonObject = JSONObject.parseObject(chargeInfoBefore);
            if (jsonObject == null) {
                jsonObject = new JSONObject();
            }
            jsonObject.put(nowTime, jsonMap);
            chargeInfo = jsonObject.toJSONString();
            chargePileOrderInfo.setChargeInfo(chargeInfo);
            //修改信息
            boolean isUpdate = chargePileOrderInfoMapper.updateChargePileOrderInfo(chargePileOrderInfo);
            if (!isUpdate) {
                log.error("————————————————————————————充电过程中修改实时数据失败————————————————————————————>");
            }
        } else {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(nowTime, jsonMap);
            chargeInfo = jsonObject.toJSONString();
            chargePileOrderInfo.setChargeInfo(chargeInfo);

            //添加信息
            boolean isAdd = chargePileOrderInfoMapper.insertChargePileOrderInfo(chargePileOrderInfo);
            //修改开始SOC
            if (!isAdd) {
                log.error("————————————————————————————充电过程中添加实时数据失败————————————————————————————>");
            }
        }

        //存入redis信息
        ChargePileOrderInfo redisInfo = redisCache.getCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum);
        if (redisInfo == null || redisInfo.getOrderCode() == null) {
            log.error("充电过程中获取实时数据redis早于添加");
//            chargePileOrderInfo.setOrderCode(chargePileOrderInfos.get(0).getOrderCode());
//            redisCache.setCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum, chargePileOrderInfo);
        } else {
            redisInfo.setTransactionNum(transactionNum);
            redisInfo.setOutVoltage(outV);
            redisInfo.setOutCurrent(outI);
            redisInfo.setPower(power);
            redisInfo.setSoc(SOC);
            redisInfo.setAccumulateChargeTime(Long.parseLong(accumulateChargeTime));
            redisInfo.setResidueTime(Long.parseLong(residueTime));
            redisInfo.setChargeKwh(chargeKwh);
            redisInfo.setLossChargeKwh(lossChargeKwh);
            redisInfo.setChargeMoney(new BigDecimal(chargeMoney));
            redisInfo.setChargeInfo(chargeInfo);
            redisCache.setCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum, redisInfo);
        }


        //查询是否是第三方订单
        ChargeOtherOrderInfo chargeOtherOrderInfo = chargeOtherOrderInfoMapper.selectChargeOtherOrderInfoByTransactionNum(transactionNum);
        if (chargeOtherOrderInfo == null) {
            //微信订单
            ChargeCustomOrderInfo chargeCustomOrderInfo = new ChargeCustomOrderInfo();
            chargeCustomOrderInfo.setTotalTime(Long.valueOf(accumulateChargeTime));
            chargeCustomOrderInfo.setTotalPower(new BigDecimal(chargeKwh));
            chargeCustomOrderInfo.setChargeMoney(new BigDecimal(chargeMoney));

            if (chargePileOrderInfos != null && chargePileOrderInfos.size() > 0) {
                if (chargePileOrderInfos.get(0).getSoc() == null || chargePileOrderInfos.get(0).getSoc().equals("0")) {
                    if (new BigDecimal(SOC).compareTo(BigDecimal.ZERO) > 0) {
                        chargeCustomOrderInfo.setStartSoc(SOC);
                    }
                    chargeCustomOrderInfo.setOrderStatus("1");
                } else {
                    chargeCustomOrderInfo.setEndSoc(SOC);
                }
            }

            chargeCustomOrderInfo.setOrderInfoCode(redisInfo.getOrderCode());

            //修改订单信息
            int isAddNumber = chargeCustomOrderInfoMapper.updateChargeCustomOrderInfoByCode(chargeCustomOrderInfo);
            if (isAddNumber != 1) {
                log.error("————————————————————————————充电过程中根据实时数据修改订单信息失败————————————————————————————>");
            }

        } else {
            //第三方订单逻辑
            chargeOtherOrderInfo.setTotalTime(Long.valueOf(accumulateChargeTime));
            chargeOtherOrderInfo.setTotalPower(new BigDecimal(chargeKwh));
            chargeOtherOrderInfo.setChargeMoney(new BigDecimal(chargeMoney));

            if (chargePileOrderInfos != null && chargePileOrderInfos.size() > 0) {
                if (chargePileOrderInfos.get(0).getSoc() == null || chargePileOrderInfos.get(0).getSoc().equals("0")) {
                    if (new BigDecimal(SOC).compareTo(BigDecimal.ZERO) > 0) {
                        chargeOtherOrderInfo.setStartSoc(SOC);
                    }
                    chargeOtherOrderInfo.setOrderStatus("1");
                } else {
                    chargeOtherOrderInfo.setEndSoc(SOC);
                }
            }

            chargeOtherOrderInfo.setTransactionNum(transactionNum);

            //修改订单信息
            boolean b = chargeOtherOrderInfoMapper.updateChargeOtherOrderInfo(chargeOtherOrderInfo);
            if (!b) {
                log.error("————————————————————————————充电过程中根据实时数据修改第三方订单信息失败————————————————————————————>");
            }
        }

    }

    //订单结束报文
    public void endOrderInfo(Map<String, Object> properties) {
        log.error("————————————————————————————订单结束,0x19  1————————————————————————————>");
        //交易流水号
        String transactionNum = String.valueOf(properties.get("transactionNum"));
        //中止荷电状态SOC
        String BMSCarBatteryStopSoc = String.valueOf(properties.get("BMSCarBatteryStopSoc"));
        //电桩累计充电时间min
        String pileSumChargeTime = String.valueOf(properties.get("pileSumChargeTime"));
        //电桩输出能量
        String pileOutEnergy = String.valueOf(properties.get("pileOutEnergy"));

        ChargePileOrderInfo redisInfo = redisCache.getCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum);

        //查询是否是第三方订单
        ChargeOtherOrderInfo chargeOtherOrderInfo = chargeOtherOrderInfoMapper.selectChargeOtherOrderInfoByTransactionNum(transactionNum);
        if (chargeOtherOrderInfo == null) {
            chargeOtherOrderInfo.setTransactionNum(transactionNum);
            //修改终止SOC
            chargeOtherOrderInfo.setEndSoc(BMSCarBatteryStopSoc);
            chargeOtherOrderInfo.setTotalTime(Long.parseLong(pileSumChargeTime));
            chargeOtherOrderInfo.setOrderStatus("2");
            log.error("————————————————————————————订单结束,0x19  3————————————————————————————>");
            //修改订单信息
            boolean b = chargeOtherOrderInfoMapper.updateChargeOtherOrderCode(chargeOtherOrderInfo);
            if (!b) {
                log.error("————————————————————————————订单结束报文根据数据修改第三方订单信息失败————————————————————————————>");
            } else {
                log.error("————————————————————————————订单结束报文根据数据修改第三方订单信息成功————————————————————————————>");
            }

        } else {
            ChargeCustomOrderInfo chargeCustomOrderInfo = chargeCustomOrderInfoMapper.selectChargeCustomOrderInfoByOrderInfoCode(redisInfo.getOrderCode());
            log.error("————————————————————————————订单结束,0x19  2————————————————————————————>");
//        Date startTime = chargeCustomOrderInfo.getStartTime();
//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(startTime);
//        int hoursToAdd = Integer.parseInt(pileSumChargeTime);
//        calendar.add(Calendar.MINUTE, hoursToAdd);
//        calendar.add(Calendar.MINUTE, hoursToAdd);
            //修改终止SOC
            chargeCustomOrderInfo.setEndSoc(BMSCarBatteryStopSoc);
//        chargeCustomOrderInfo.setEndTime(calendar.getTime());
//        chargeCustomOrderInfo.setTotalPower(new BigDecimal(pileOutEnergy));
            chargeCustomOrderInfo.setTotalTime(Long.parseLong(pileSumChargeTime));
            chargeCustomOrderInfo.setOrderStatus("2");
            log.error("————————————————————————————订单结束,0x19  3————————————————————————————>");
            if (chargeCustomOrderInfo.getPriceTypeCode() != null && !StringUtils.isEmpty(chargeCustomOrderInfo.getPriceTypeCode())) {
                try {
                    /*chargeCustomOrderInfo = */
                    chargeCustomOrderInfoService.getOrderPriceDetails(chargeCustomOrderInfo);
                } catch (Exception e) {
                    log.error("————————————————————————————交易订单,结束充电,计算服务费、电费出现异常————————————————————————————>" + e);
                    e.printStackTrace();
                }
            }

            //修改订单信息
            int isAddNumber = chargeCustomOrderInfoMapper.updateChargeCustomOrderInfoByCode(chargeCustomOrderInfo);
            if (isAddNumber != 1) {
                log.error("————————————————————————————订单结束报文根据数据修改订单信息失败————————————————————————————>");
            } else {
                log.error("————————————————————————————订单结束报文根据数据修改订单信息成功————————————————————————————>");
            }
        }

    }

    //交易订单
    public void transactionRecords(Map<String, Object> properties) {
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //交易流水号
            String transactionNum = String.valueOf(properties.get("transactionNum"));
            //桩号
            String pileNumber = String.valueOf(properties.get("pileNumber"));
            //订单表否有有该信息
            ChargePileOrderInfo chargePileOrderInfoCheck = chargePileOrderInfoMapper.selectChargePileOrderInfoByCode(transactionNum);
            if (chargePileOrderInfoCheck == null) {
                return;
            } else {
                Map<String, Object> stringObjectMap
                        = remoteInstructSendService.transactionRecordConfirmation(pileNumber, transactionNum, "00", "YTSN-CDZ-N01");
            }
            //枪号
            String gunNumber = String.valueOf(properties.get("gunNumber"));
            //开始时间
            Date startTime = format.parse(properties.get("startTime").toString());
            //结束时间
            Date endTime = format.parse(properties.get("endTime").toString());
            //尖单价(精确到小数点后五位（尖电费+尖服务费，见费率帧）)
            String pointedUnitPrice = String.valueOf(properties.get("pointedUnitPrice"));
            //尖电量(精确到小数点后四位)
            String pointedKwh = String.valueOf(properties.get("pointedKwh"));
            //损尖电量(精确到小数点后四位)
            String pointedLossKwh = String.valueOf(properties.get("pointedLossKwh"));
            //尖金额(精确到小数点后四位)
            String pointedMoney = String.valueOf(properties.get("pointedMoney"));
            //峰单价(精确到小数点后五位（峰电费+峰服务费，见费率帧）)
            String peakUnitPrice = String.valueOf(properties.get("peakUnitPrice"));
            //峰电量(精确到小数点后四位)
            String peakKwh = String.valueOf(properties.get("peakKwh"));
            //损峰电量(精确到小数点后四位)
            String peakLossKwh = String.valueOf(properties.get("peakLossKwh"));
            //峰金额(精确到小数点后四位)
            String peakMoney = String.valueOf(properties.get("peakMoney"));
            //平单价(精确到小数点后五位（平电费+平服务费，见费率帧）)
            String flatUnitPrice = String.valueOf(properties.get("flatUnitPrice"));
            //平电量(精确到小数点后四位)
            String flatKwh = String.valueOf(properties.get("flatKwh"));
            //损平电量(精确到小数点后四位)
            String flatLossKwh = String.valueOf(properties.get("flatLossKwh"));
            //平金额(精确到小数点后四位)
            String flatMoney = String.valueOf(properties.get("flatMoney"));
            //谷单价(精确到小数点后五位（谷电费+谷服务费，见费率帧）)
            String valleyUnitPrice = String.valueOf(properties.get("valleyUnitPrice"));
            //谷电量(精确到小数点后四位)
            String valleyKwh = String.valueOf(properties.get("valleyKwh"));
            //损谷电量(精确到小数点后四位)
            String valleyLossKwh = String.valueOf(properties.get("valleyLossKwh"));
            //谷金额(精确到小数点后四位)
            String valleyMoney = String.valueOf(properties.get("valleyMoney"));
            //电表总起值(精确到小数点后四位)
            String electricityMeterStartPrice = String.valueOf(properties.get("electricityMeterStartPrice"));
            //电表总止值(精确到小数点后四位)
            String electricityMeterStopPrice = String.valueOf(properties.get("electricityMeterStopPrice"));
            //总电量(精确到小数点后四位)
            String assembleKwh = String.valueOf(properties.get("assembleKwh"));
            //计损总电量(精确到小数点后四位)
            String assembleLossKwh = String.valueOf(properties.get("assembleLossKwh"));
            //消费金额(精确到小数点后四位，包含电费、服务费)
            String assembleMoney = String.valueOf(properties.get("assembleMoney"));
            //电动汽车唯一标识(VIN 码，此处 VIN 码和充电时 VIN码不同，正序直接上传，无需补 0和反序)
            String carVin = String.valueOf(properties.get("carVin"));
            //交易标识(0x01：app 启动0x02：卡启动0x04：离线卡启动0x05: vin 码启动充电)
            String transactionIdentifier = String.valueOf(properties.get("transactionIdentifier"));
            //交易日期、时间
            Date transactionTime = format.parse(properties.get("transactionTime").toString());
            //停止原因
            String stopReason = String.valueOf(properties.get("stopReason"));
            log.error("————————————————————————————停止原因————————————————————————————>" + stopReason);
            if ("40".equals(stopReason)) {
                stopReason = "结束充电，APP 远程停止";
            } else if ("41".equals(stopReason)) {
                stopReason = "结束充电，SOC 达到 100%";
            } else if ("42".equals(stopReason)) {
                stopReason = "结束充电，充电电量满足设定条件";
            } else if ("43".equals(stopReason)) {
                stopReason = "结束充电，充电金额满足设定条件";
            } else if ("44".equals(stopReason)) {
                stopReason = "结束充电，充电时间满足设定条件";
            } else if ("45".equals(stopReason)) {
                stopReason = "结束充电，手动停止充电";
            } else {
                stopReason = "其他";
            }
            //物理卡号(不足 8 位补 0)
            String physicsCard = String.valueOf(properties.get("physicsCard"));

            //添加到充电过程中实时数据交易订单信息
            ChargePileOrderInfo chargePileOrderInfo = new ChargePileOrderInfo(transactionNum, pileNumber, gunNumber,
                    startTime, endTime, pointedUnitPrice, pointedKwh, pointedLossKwh, pointedMoney, peakUnitPrice, peakKwh,
                    peakLossKwh, peakMoney, flatUnitPrice, flatKwh, flatLossKwh, flatMoney, valleyUnitPrice, valleyKwh,
                    valleyLossKwh, valleyMoney, electricityMeterStartPrice,
                    electricityMeterStopPrice, assembleKwh, assembleLossKwh, assembleMoney,
                    carVin, transactionIdentifier, transactionTime, stopReason, physicsCard);

            //是否有相同的订单信息
            ChargePileOrderInfo chargePileOrderInfos = chargePileOrderInfoMapper.selectChargePileOrderInfoByCode(transactionNum);

            if (chargePileOrderInfos != null && chargePileOrderInfos.getOrderCode() != null) {
                chargePileOrderInfo.setOrderCode(chargePileOrderInfos.getOrderCode());
                //修改信息
                boolean isUpdate = chargePileOrderInfoMapper.updateChargePileOrderInfo(chargePileOrderInfo);
                if (!isUpdate) {
                    log.error("————————————————————————————充电完毕后修改交易订单信息数据失败————————————————————————————>");
                }
            } else {
                //添加信息
                boolean isAdd = chargePileOrderInfoMapper.insertChargePileOrderInfo(chargePileOrderInfo);
                if (!isAdd) {
                    log.error("————————————————————————————充电完毕后添加交易订单信息数据失败————————————————————————————>");
                }
            }


            //完善redis信息
            ChargePileOrderInfo chargePileOrderInfoRedis = chargePileOrderInfoMapper.selectChargePileOrderInfoByCode(transactionNum);
            //存入redis
            ChargePileOrderInfo redisInfo = redisCache.getCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum);
            redisInfo.setStopState("1");
            if (redisInfo == null) {
                redisCache.setCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum, chargePileOrderInfoRedis);
            } else {
                if (redisInfo.getStartState() != null) {
                    chargePileOrderInfoRedis.setStartState(redisInfo.getStartState());
                }

                if (redisInfo.getStopState() != null) {
                    chargePileOrderInfoRedis.setStopState(redisInfo.getStopState());
                }
                redisCache.setCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum, chargePileOrderInfoRedis);
            }

            //查询是否是第三方订单
            ChargeOtherOrderInfo chargeOtherOrderInfo = chargeOtherOrderInfoMapper.selectChargeOtherOrderInfoByTransactionNum(transactionNum);
            if (chargeOtherOrderInfo == null) {
                //微信支付订单

                //操作步骤 - 结束充电
                ChargeCustomOrderInfoProcess chargeCustomOrderInfoProcess = new ChargeCustomOrderInfoProcess();
                chargeCustomOrderInfoProcess.setOrderInfoCode(redisInfo.getOrderCode());//订单号
                chargeCustomOrderInfoProcess.setOrderInfoProcessName("结束充电");
                chargeCustomOrderInfoProcess.setOrderInfoProcessResult("1");
                chargeCustomOrderInfoProcess.setOrderInfoProcessCreateTime(new Date());//时间
                boolean isUpdate = chargeCustomOrderInfoProcessMapper.updateChargeCustomOrderInfoProcessByCode(chargeCustomOrderInfoProcess);
                if (!isUpdate) {
                    log.error("————————————————————————————交易订单,修改操作步骤失败————————————————————————————>");
                } else {
                    log.error("————————————————————————————交易订单,结束充电,修改操作步骤成功————————————————————————————>");
                }

                //查询订单信息
                ChargeCustomOrderInfo chargeCustomOrderInfo = chargeCustomOrderInfoMapper.selectChargeCustomOrderInfoByOrderInfoCode(chargePileOrderInfos.getOrderCode());
                chargeCustomOrderInfo.setStartTime(startTime);//充电开始时间
                chargeCustomOrderInfo.setEndTime(endTime);//充电结束时间
                chargeCustomOrderInfo.setChargeMoney(new BigDecimal(assembleMoney));//已充金额
                chargeCustomOrderInfo.setStopReason(stopReason);
                chargeCustomOrderInfo.setTotalPower(new BigDecimal(assembleKwh));//已充总电量
                //计算服务费、电费
                if (chargeCustomOrderInfo.getPriceTypeCode() != null && !StringUtils.isEmpty(chargeCustomOrderInfo.getPriceTypeCode())) {
                    try {
                        /*chargeCustomOrderInfo = */
                        chargeCustomOrderInfoService.getOrderPriceDetails(chargeCustomOrderInfo);
                    } catch (Exception e) {
                        log.error("————————————————————————————交易订单,结束充电,计算服务费、电费出现异常————————————————————————————>" + e);
                        e.printStackTrace();
                    }
                }


                //发起退款
                WxPay wxPay = new WxPay();
                //商户订单号
                wxPay.setOutTradeNo(redisInfo.getOrderCode());
                if (!StringUtils.isEmpty(assembleMoney) && new BigDecimal(assembleMoney).compareTo(BigDecimal.ZERO) > 0) {
                    //计算退款金额(元)
                    BigDecimal paymentAmount = chargeCustomOrderInfo.getPaymentAmount().compareTo(BigDecimal.ZERO) == 0 ? chargeCustomOrderInfo.getTotalMoney() : chargeCustomOrderInfo.getPaymentAmount();
                    BigDecimal diffMoney = paymentAmount.subtract(new BigDecimal(assembleMoney));
                    log.error("————————————————————————————退款金额————————————————————————————>" + diffMoney);
                    //结束订单
                    chargeCustomOrderInfo.setOrderStatus("2");
                    if (diffMoney.equals(BigDecimal.ZERO)) {
//                    //结束订单
//                    chargeCustomOrderInfo.setOrderStatus("2");
                    } else {
                        //退款金额
                        chargeCustomOrderInfo.setRefundAmount(diffMoney);
                        wxPay.setMoney(String.valueOf(diffMoney));
                        WxPay refund = wXPayService.refund(wxPay);
                        if (refund.getStatus() == 500) {
                            log.error("————————————————————————————" + refund.getMsg() + "————————————————————————————>");
                        }
                    }
                    int i = chargeCustomOrderInfoMapper.updateChargeCustomOrderInfo(chargeCustomOrderInfo);
                    if (i != 1) {
                        log.error("————————————————————————————交易订单修改微信订单信息失败————————————————————————————>");
                    }
                    //操作步骤 - 结算完毕
                    ChargeCustomOrderInfoProcess chargeCustomOrderInfoProcessE = new ChargeCustomOrderInfoProcess();
                    chargeCustomOrderInfoProcessE.setOrderInfoCode(redisInfo.getOrderCode());//订单号
                    chargeCustomOrderInfoProcessE.setOrderInfoProcessName("结算完毕");
                    chargeCustomOrderInfoProcessE.setOrderInfoProcessResult("1");
                    chargeCustomOrderInfoProcessE.setOrderInfoProcessCreateTime(new Date());//时间
                    isUpdate = chargeCustomOrderInfoProcessMapper.updateChargeCustomOrderInfoProcessByCode(chargeCustomOrderInfoProcessE);
                    if (!isUpdate) {
                        log.error("————————————————————————————结算完毕,修改操作步骤失败————————————————————————————>");
                    } else {
                        log.error("————————————————————————————结算完毕,修改操作步骤成功————————————————————————————>");
                    }

                    /********添加累计统计信息*********/
                    this.changeStatisticsInfo(chargeCustomOrderInfo, null, assembleKwh);


                    //向设备推送信息
//                String channel = chargeCustomOrderInfo.getCustomCode() + chargeCustomOrderInfo.getDeviceCode() + chargeCustomOrderInfo.getPortId();
                    WebSocketService webSocketService = new WebSocketService();
                    webSocketService.postEventOpenId(chargeCustomOrderInfo.getCustomCode(), "1", stopReason, "end",
                            chargeCustomOrderInfo.getDeviceCode(), chargeCustomOrderInfo.getPortId());

                }

            } else {
                //第三方订单

                chargeOtherOrderInfo.setTransactionNum(transactionNum);
                chargeOtherOrderInfo.setStartTime(startTime);//充电开始时间
                chargeOtherOrderInfo.setEndTime(endTime);//充电结束时间
                chargeOtherOrderInfo.setChargeMoney(new BigDecimal(assembleMoney));//已充金额
                chargeOtherOrderInfo.setStopReason(stopReason);
                chargeOtherOrderInfo.setTotalPower(new BigDecimal(assembleKwh));//已充总电量
                chargeOtherOrderInfo.setOrderStatus("2");

                /********添加累计统计信息*********/
                this.changeStatisticsInfo(null, chargeOtherOrderInfo, assembleKwh);

                boolean b = chargeOtherOrderInfoMapper.updateChargeOtherOrderCode(chargeOtherOrderInfo);
                if (!b) {
                    log.error("————————————————————————————交易订单修改第三方订单信息失败————————————————————————————>");
                }
            }

        } catch (Exception e) {
            log.error("————————————————————————————交易订单保温上报保存信息出现异常————————————————————————————> " + e);
            e.printStackTrace();
        }

    }

    //订单统计信息
    public void changeStatisticsInfo(ChargeCustomOrderInfo chargeCustomOrderInfo, ChargeOtherOrderInfo chargeOtherOrderInfo,
                                     String assembleKwh) {
        Boolean isUpdate = false;
        String portId = "";
        if (chargeCustomOrderInfo == null) {
            portId = chargeCustomOrderInfo.getPortId();
        } else {
            portId = chargeOtherOrderInfo.getPortId();
        }


        //是否存在
        ChargeStatisticsInfo checkInfo = chargeStatisticsInfoMapper.selectChargeStatisticsInfoByPortId(portId);
        if (checkInfo == null) {
            //添加
            ChargeStatisticsInfo chargeStatisticsInfo = new ChargeStatisticsInfo(chargeCustomOrderInfo.getDeviceCode(),
                    chargeCustomOrderInfo.getPortId(), new BigDecimal(assembleKwh), 1L);
            chargeStatisticsInfo.setCreateTime(DateUtils.getNowDate());
            isUpdate = chargeStatisticsInfoMapper.insertChargeStatisticsInfo(chargeStatisticsInfo);
            if (!isUpdate) {
                log.error("————————————————————————————结算完毕,添加累计充电信息失败————————————————————————————>");
            } else {
                log.error("————————————————————————————结算完毕,添加累计充电信息成功————————————————————————————>");
            }
        } else {
            //修改
            ChargeStatisticsInfo chargeStatisticsInfo = new ChargeStatisticsInfo(chargeCustomOrderInfo.getDeviceCode(),
                    chargeCustomOrderInfo.getPortId(), checkInfo.getChargeKwhSum().add(new BigDecimal(assembleKwh)).setScale(4, RoundingMode.HALF_UP)
                    , checkInfo.getChargeNum() + 1L);
            isUpdate = chargeStatisticsInfoMapper.updateChargeStatisticsInfo(chargeStatisticsInfo);
            if (!isUpdate) {
                log.error("————————————————————————————结算完毕,修改累计充电信息失败————————————————————————————>");
            } else {
                log.error("————————————————————————————结算完毕,修改累计充电信息成功————————————————————————————>");
            }
        }
    }


    //启动回复
    public void startReply(Map<String, Object> properties) {
        Date date = new Date();
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        String format = sdf.format(date);
        //交易流水号
        String transactionNum = String.valueOf(properties.get("transactionNum"));
        //桩号
        String pileNumber = String.valueOf(properties.get("pileNumber"));
        //枪号
        String gunNumber = String.valueOf(properties.get("gunNumber"));
        //启动结果(0失败 1成功)
        String startResult = String.valueOf(properties.get("startResult"));
        //失败原因(0 无 1 设备编号不匹配 2 枪已在充电 3 设备故障 4 设备离线 5 未插枪)
        String startFailureReason = String.valueOf(properties.get("startFailureReason"));

        //存入redis开启信息
        ChargePileOrderInfo redisInfo = redisCache.getCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum);
        if (redisInfo == null) {
            ChargePileOrderInfo chargePileOrderInfo = new ChargePileOrderInfo(transactionNum, startResult, startFailureReason);
            chargePileOrderInfo.setStartTime(date);
            redisCache.setCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum, chargePileOrderInfo);
        } else {
            redisInfo.setStartTime(date);
            redisInfo.setStartState(startResult);
            redisInfo.setStartFailureReason(startFailureReason);
            redisCache.setCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum, redisInfo);
        }


        //查询是否是第三方订单
        ChargeOtherOrderInfo chargeOtherOrderInfo = chargeOtherOrderInfoMapper.selectChargeOtherOrderInfoByTransactionNum(transactionNum);
        if (chargeOtherOrderInfo == null) {
            //微信支付订单
            if ("1".equals(startResult)) {
                //操作步骤 - 开始充电
                ChargeCustomOrderInfoProcess chargeCustomOrderInfoProcess = new ChargeCustomOrderInfoProcess();
                chargeCustomOrderInfoProcess.setOrderInfoCode(redisInfo.getOrderCode());//订单号
                chargeCustomOrderInfoProcess.setOrderInfoProcessName("开始充电");
                chargeCustomOrderInfoProcess.setOrderInfoProcessResult("1");
                chargeCustomOrderInfoProcess.setOrderInfoProcessCreateTime(new Date());//时间
                boolean isUpdate = chargeCustomOrderInfoProcessMapper.updateChargeCustomOrderInfoProcessByCode(chargeCustomOrderInfoProcess);
                if (!isUpdate) {
                    log.error("————————————————————————————启动回复,修改操作步骤失败————————————————————————————>");
                } else {
                    log.error("————————————————————————————启动回复,开始充电，修改操作步骤成功————————————————————————————>");
                }
            }


            //查询订单信息
            ChargeCustomOrderInfo chargeCustomOrderInfo = chargeCustomOrderInfoMapper.selectChargeCustomOrderInfoByOrderInfoCode(redisInfo.getOrderCode());
//        String channel = chargeCustomOrderInfo.getCustomCode() + chargeCustomOrderInfo.getDeviceCode() + chargeCustomOrderInfo.getPortId();

            chargeCustomOrderInfo.setOrderStatus("1");
            chargeCustomOrderInfo.setStartTime(date);

            int i = chargeCustomOrderInfoMapper.updateChargeCustomOrderInfoByCode(chargeCustomOrderInfo);
            if (i != 1) {
                log.error("————————————————————————————启动回复,开始充电，修改微信支付订单充电状态失败————————————————————————————>");
            }

            //向设备推送信息1
            WebSocketService webSocketService = new WebSocketService();
            webSocketService.postEventOpenId(chargeCustomOrderInfo.getCustomCode(), startResult, startFailureReason, "start",
                    chargeCustomOrderInfo.getDeviceCode(), chargeCustomOrderInfo.getPortId());

        } else {
            //第三方订单
            chargeOtherOrderInfo.setTransactionNum(transactionNum);
            chargeOtherOrderInfo.setOrderStatus("1");
            chargeOtherOrderInfo.setStartTime(date);

            boolean b = chargeOtherOrderInfoMapper.updateChargeOtherOrderCode(chargeOtherOrderInfo);

            //启动充电回复
//            StartChargeSeq   充电订单号    格式(运营商ID+唯一编码) 27字符
//            StartChargeSeqSrat    充电订单状态 1-启动中 2-充电中 3-停止中 4-已结束 5-未知 格式（0）
//            ConnectorID    充电设备接口编码    ？？？？ 格式（""）
//            StartTime    充电启动时间  格式（yyyy-MM-dd HH:mm:ss）
//            IdentCode    停止充电验证码  启动充电是收到的验证码，用于点状手动停止充电 格式（""）
            apiController.notification_start_charge_result(chargeOtherOrderInfo.getOtherOrderCode(),
                    "1", pileNumber + gunNumber, "", "");

            if (!b) {
                log.error("————————————————————————————启动回复,开始充电，修改第三方订单充电状态失败————————————————————————————>");
            }
        }

    }

    //停止回复
    public void endReply(Map<String, Object> properties) {
//        //交易流水号
//        String transactionNum = String.valueOf(properties.get("transactionNum"));
        //桩号
        String pileNumber = String.valueOf(properties.get("pileNumber"));
        //枪号
        String gunNumber = String.valueOf(properties.get("gunNumber"));
        //停止结果(0失败 1成功)
        String stopResult = String.valueOf(properties.get("stopResult"));
        //失败原因(0 无 1 设备编号不匹配 2 枪未处于充电状态 3 其他)
        String stopFailureReason = String.valueOf(properties.get("stopFailureReason"));
//        //存入redis关闭信息
//        ChargePileOrderInfo redisInfo = redisCache.getCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum);
//        if (redisInfo == null) {
//            ChargePileOrderInfo chargePileOrderInfo = new ChargePileOrderInfo(transactionNum, "1", stopResult);
//            redisCache.setCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum, chargePileOrderInfo);
//        } else {
//            redisInfo.setStopState(stopResult);
//            redisCache.setCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum, redisInfo);
//        }
    }

    //充电握手
    public void chargingHandShake(Map<String, Object> properties) {
        //交易流水号
        String transactionNum = String.valueOf(properties.get("transactionNum"));
        //桩号
        String pileNumber = String.valueOf(properties.get("pileNumber"));
        //枪号
        String gunNumber = String.valueOf(properties.get("gunNumber"));
        //BMS 通信协议版本号
        String BMSVersion = String.valueOf(properties.get("BMSVersion"));
        //BMS 电池类型(电池类型,1:铅酸电池;2:氢电池;3:磷酸铁锂电池;4:锰酸锂电池;5:钴酸锂电池;6:三元材料电池;7:聚合物锂离子电池;8:钛酸锂电池;255:其他;)
        String BMSType = String.valueOf(properties.get("BMSType"));
        //BMS 整车动力蓄电池系统额定容量
        String BMSRatedCapacity = String.valueOf(properties.get("BMSRatedCapacity"));
        //BMS 整车动力蓄电池系统额定总电压
        String BMSRatedV = String.valueOf(properties.get("BMSRatedV"));
        //BMS 电池生产厂商名称
        String batteryManufacturer = String.valueOf(properties.get("batteryManufacturer"));
        //BMS 电池组序号
        String batteryPackNumber = String.valueOf(properties.get("batteryPackNumber"));
        //BMS 电池组生产日期
        String chargeProduceTime = String.valueOf(properties.get("chargeProduceTime"));
        //BMS 电池组充电次数
        String chargeNumber = String.valueOf(properties.get("chargeNumber"));
        //BMS 电池组产权标识（<0>：=租赁；<1>：=车自有）
        String chargeOwnership = String.valueOf(properties.get("chargeOwnership"));
        //预留
        String reserve = String.valueOf(properties.get("reserve"));
        //BMS 车辆识别码
        String carVin = String.valueOf(properties.get("carVin"));
        //BMS 软件版本号
        String BMSSoftwareVersion = String.valueOf(properties.get("BMSSoftwareVersion"));
    }

    //参数配置
    public void parameterConfiguration(Map<String, Object> properties) {
        //交易流水号
        String transactionNum = String.valueOf(properties.get("transactionNum"));
        //桩号
        String pileNumber = String.valueOf(properties.get("pileNumber"));
        //枪号
        String gunNumber = String.valueOf(properties.get("gunNumber"));
        //BMS 单体动力蓄电池最高允许充电电压（数据范围：0~24 V）
        String BMSMaxChargeV = String.valueOf(properties.get("BMSMaxChargeV"));
        //BMS BMS 最高允许充电电流
        String BMSMaxChargeI = String.valueOf(properties.get("BMSMaxChargeI"));
        //BMS 动力蓄电池标称总能量（数据范围：0~1000 kWh）
        String BMSSumEnergy = String.valueOf(properties.get("BMSSumEnergy"));
        //BMS 最高允许充电总电压
        String BMSSumV = String.valueOf(properties.get("BMSSumV"));
        //BMS 最高允许温度（数据范围：-50 ºC ~+200 ºC）
        String BMSMaxTemp = String.valueOf(properties.get("BMSMaxTemp"));
        //BMS 整车动力蓄电池荷电状态soc（数据范围：0~100%）
        String BMSCarBatterySoc = String.valueOf(properties.get("BMSCarBatterySoc"));
        //BMS 整车动力蓄电池当前电池电压
        String BMSNowChargeV = String.valueOf(properties.get("BMSNowChargeV"));
        //电桩最高输出电压
        String pileMaxV = String.valueOf(properties.get("pileMaxV"));
        //电桩最低输出电压
        String pileMinV = String.valueOf(properties.get("pileMinV"));
        //电桩最大输出电流
        String pileMaxI = String.valueOf(properties.get("pileMaxI"));
        //电桩最低输出电流
        String pileMinI = String.valueOf(properties.get("pileMinI"));
        //电桩最高输出功率
        String maxPower = String.valueOf(properties.get("maxPower"));
        //电桩最低输出功率
        String minPower = String.valueOf(properties.get("minPower"));
    }

    //充电过程
    public void chargingProcess(Map<String, Object> properties) {
        //交易流水号
        String transactionNum = String.valueOf(properties.get("transactionNum"));
        //桩号
        String pileNumber = String.valueOf(properties.get("pileNumber"));
        //枪号
        String gunNumber = String.valueOf(properties.get("gunNumber"));
        //BMS 电压需求
        String BMSVDemand = String.valueOf(properties.get("BMSVDemand"));
        //BMS 电流需求
        String BMSIDemand = String.valueOf(properties.get("BMSIDemand"));
        //BMS 充电模式（1：恒压充电；2：恒流充电）
        String BMSChargeMode = String.valueOf(properties.get("BMSChargeMode"));
        //BMS 充电电压测量值
        String BMSVMeasure = String.valueOf(properties.get("BMSVMeasure"));
        //BMS 充电电流测量值
        String BMSIMeasure = String.valueOf(properties.get("BMSIMeasure"));
        //BMS 最高单体动力蓄电池电压及组号
        String BMSMaxMonomerV = String.valueOf(properties.get("BMSMaxMonomerV"));
        //BMS 当前荷电状态 SOC
        String BMSChargedSOC = String.valueOf(properties.get("BMSChargedSOC"));
        //BMS 估算剩余充电时间（数据范围：0~600 min）
        String BMSEstimateChargeTime = String.valueOf(properties.get("BMSEstimateChargeTime"));
        //电桩电压输出值
        String pileOutV = String.valueOf(properties.get("pileOutV"));
        //电桩电流输出值
        String pileOutI = String.valueOf(properties.get("pileOutI"));
        //累计充电时间（数据范围：0~600 min）
        String countChargeTime = String.valueOf(properties.get("countChargeTime"));

        ChargePileOrderInfo chargePileOrderInfo = new ChargePileOrderInfo();
        chargePileOrderInfo.setTransactionNum(transactionNum);
        //是否有相同的订单信息
        List<ChargePileOrderInfo> chargePileOrderInfos = chargePileOrderInfoMapper.selectChargePileOrderInfoList(chargePileOrderInfo);
        if (chargePileOrderInfos.size() > 0) {
            String chargeInfoBefore = chargePileOrderInfos.get(0).getChargeInfo();
            JSONObject jsonObject = JSONObject.parseObject(chargeInfoBefore);
            //追加数据
            Map<String, Map<String, Object>> map = jsonObject.toJavaObject(Map.class);
            Map<String, Map<String, Object>> result = new LinkedHashMap<>();
            map.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEachOrdered(x -> result.put(x.getKey(), x.getValue()));
            List<Map.Entry<String, Map<String, Object>>> collect = result.entrySet().stream().collect(Collectors.toList());
            Map<String, Object> value = collect.get(collect.size() - 1).getValue();
            value.put("needV", BMSVDemand);
            value.put("needI", BMSIDemand);
            String jsonObject1 = JSON.toJSONString(map);
            chargePileOrderInfos.get(0).setChargeInfo(jsonObject1);

            //修改信息
            boolean isUpdate = chargePileOrderInfoMapper.updateChargePileOrderInfo(chargePileOrderInfos.get(0));
            if (!isUpdate) {
                log.error("————————————————————————————追加json数据,修改实时信息失败————————————————————————————>");
            } else {
                log.error("————————————————————————————追加json数据,修改实时信息成功————————————————————————————>");
            }

            //存入redis信息
            ChargePileOrderInfo redisInfo = redisCache.getCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum);
            redisInfo.setChargeInfo(jsonObject1);
            redisCache.setCacheMapValue(RedisKeyConstants.PILE_PORT_ORDER_INFO, transactionNum, redisInfo);
        } else {
            log.error("————————————————————————————追加json数据,数据库未取到数据————————————————————————————>");
        }
    }

    //充电桩计费模型请求
    public void billingRequest(Map<String, Object> properties) {
        //桩号
        String pileNumber = String.valueOf(properties.get("pileNumber"));
        List<String> deviceIdList = new ArrayList<String>() {{
            add(pileNumber);
        }};
        //获取充电桩当前价格策略
        Map<String, Object> priceTypeId = chargeStationPileMapper.getPriceTypeId(pileNumber);
        if (priceTypeId != null && priceTypeId.get("priceTypeId") != null) {
            //下发价格
            long priceTypeIdLong = Long.parseLong(String.valueOf(priceTypeId.get("priceTypeId")));
            Map<String, Object> stringObjectMap =
                    remoteInstructSendService.distributeBillingTemplates(deviceIdList, priceTypeIdLong, "YTSN-CDZ-N01");
        }
    }

    //二维码下发应答
    public void QRCodeResponse(Map<String, Object> properties) {
        //桩号
        String pileNumber = String.valueOf(properties.get("pileNumber"));
        //枪号
        String gunNumber = String.valueOf(properties.get("gunNumber"));
        //设置结果（0失败，1成功）
        String QRCodeSetResult = String.valueOf(properties.get("QRCodeSetresult"));
    }

    //计费模版下发应答
    public void chargingTemplate(Map<String, Object> properties) {
        //桩号
        String pileNumber = String.valueOf(properties.get("pileNumber"));
        //设置结果（0失败，1成功）
        String chargingResult = String.valueOf(properties.get("chargingResult"));
    }

    //调度记录
    public void dispatchRecord(Map<String, Object> properties) {
        String stationCode = String.valueOf(properties.get("stationCode"));
        String dispatchType = String.valueOf(properties.get("dispatchType"));
        String dispatchTime = String.valueOf(properties.get("dispatchTime"));
        String stationRealPower = String.valueOf(properties.get("stationRealPower"));
        String setValue = String.valueOf(properties.get("setValue"));
        String deviceCode = String.valueOf(properties.get("deviceCode"));
        String setMessage = String.valueOf(properties.get("setMessage"));
        String allocationPower = String.valueOf(properties.get("allocationPower"));
        String dispatchName = "";
        if ("1".equals(dispatchType)) {
            dispatchName = "动态调度";
        } else {
            dispatchName = "预测调度";
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = dateFormat.parse(dispatchTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        ChargeStationStrategyHistory chargeStationStrategyHistory = new ChargeStationStrategyHistory();
        chargeStationStrategyHistory.setStationCode(stationCode);
        chargeStationStrategyHistory.setDispatchName(dispatchName);
        chargeStationStrategyHistory.setDispatchContent(dispatchTime + "执行了" + dispatchName + ",设置充电桩最大输出功率为" + setValue + "。");
        chargeStationStrategyHistory.setDispatchTime(date);
        chargeStationStrategyHistory.setSetValue(setValue);
        chargeStationStrategyHistory.setMaxPower(Integer.parseInt(setValue));
        chargeStationStrategyHistory.setDispatchType(dispatchType);
        chargeStationStrategyHistory.setStationRealPower(stationRealPower);
        chargeStationStrategyHistory.setAllocationPower(allocationPower);
        chargeStationStrategyHistory.setDeviceId(deviceCode);
        chargeStationStrategyHistory.setSetMessage(setMessage);
        chargeStationStrategyHistoryMapper.insertChargeStationStrategyHistory(chargeStationStrategyHistory);
    }
}
